"""
Copyright (c) 2022 Huawei Technologies Co.,Ltd.

openGauss is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:

          http://license.coscl.org.cn/MulanPSL2

THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
"""
"""
Case Type   : 人为因素
Case Name   : 有事务提交情况下，数据库异常停止
Create At   : 2020/10/13
@zou_jialiang0505328126
Description :
    1、产生持续事务
    2、kill -9数据库主进程
    3、数据库启动 gs_om -t start
Expect      :
    未修改原逻辑
History     :
    created： 2020/10/13  created by @wan005
    modified ：2020-12-4 by @peilinqian ；kill_pid方法会导致tpcc进程也被被kill，该用例只需要kill数据库进程,修改kill数据库进程方法；
    modified ：2021-01-13 by @wan005 ；teardown中增加数据库状态检查，辅助定位；
    modified ：2021-01-21 by @wan005: 重启时主备可能不一致，修改重启断言，增加等待主备一致
"""
import os
import unittest
from yat.test import Node
import time
from yat.test import macro
import sys
import datetime

sys.path.append(sys.path[0] + "/../")
from testcase.utils.Logger import Logger
from testcase.utils.Constant import Constant
from testcase.utils.Common import Common
from testcase.utils.CommonSH import *
from testcase.utils.ComThread import ComThread

logger = Logger()
common = Common('PrimaryRoot')
commonshpri = CommonSH('PrimaryDbUser')
commonshsta1 = CommonSH('Standby1DbUser')
commonshsta2 = CommonSH('Standby2DbUser')


class ModifyConnection(unittest.TestCase):
    dbPrimaryUserNode = Node(node='PrimaryDbUser')
    dbPrimaryRootNode = Node(node='PrimaryRoot')
    dbStandby1RootNode = Node(node='Standby1Root')
    dbStandby1UserNode = Node(node='Standby1DbUser')
    dbStandby2UserNode = Node(node='Standby2DbUser')
    DB_INSTANCE_PATH = macro.DB_INSTANCE_PATH
    DB_ENV_PATH = macro.DB_ENV_PATH
    constant = Constant()
    TPCC_PATH = macro.TPCC_PATH

    nodes_tuple = ('PrimaryDbUser', 'Standby1DbUser', 'Standby2DbUser')

    @RestartDbCluster(*nodes_tuple)
    def setUp(self):
        logger.info("-----------this is setup-----------")
        logger.info("-----------reliability_humanfactor010 start-----------")

    def test_modify_pidfile(self):
        logger.info("-----------start TPCC--------------------")
        tpcc_thread = ComThread(common.startTPCC, args=(self.dbPrimaryRootNode, self.TPCC_PATH))
        tpcc_thread.start()

        time.sleep(30)

        logger.info("-----------kill -9 opengauss--------------------")
        common.kill_pid_keyword('gaussdb', 9, self.dbPrimaryUserNode)
        time.sleep(1)

        logger.info("-------------start opengauss---------------------")
        result = commonshpri.startDbCluster(True)
        self.assertTrue('Degraded' in result or
                        self.constant.START_SUCCESS_MSG in result)

        logger.info("-------------check tpcc result---------------------")
        tpcc_thread.join(int(macro.TPCC_RUN_MAX_TIME) * 2)
        tpcc_result = tpcc_thread.get_result()
        logger.info(tpcc_result)
        self.assertNotIn(self.constant.TPCC_SUCCESS_MSG, tpcc_result)

        logger.info("----------------check duty page----------------------")
        result = commonshpri.check_whether_remain_dirty_page()
        self.assertTrue(result)

        logger.info("-------------check data consistency-------------------")
        flag = commonshsta1.check_data_consistency()
        self.assertTrue(flag)
        flag = commonshsta2.check_data_consistency()
        self.assertTrue(flag)

        nodes_tuple = (self.dbPrimaryUserNode, self.dbStandby1UserNode, self.dbStandby2UserNode)
        flag = common.check_data_sample_by_all(r'\d', *nodes_tuple)
        self.assertTrue(flag)

        table_dict = common.format_sql_result(commonshpri.executDbSql(r'\d'))
        table_name = table_dict.get('Name')
        for name in table_name:
            select_sql = f'select count(*) from {name};'
            flag = common.check_data_sample_by_all(select_sql, *nodes_tuple)
            self.assertTrue(flag)

    def tearDown(self):
        logger.info('----------------this is tearDown-----------------------')
        logger.info('------------查看数据库状态-----------')
        result = commonshpri.getDbClusterStatus('detail')
        logger.info(result)
